namespace Rsdn.Janus
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;

    using BLToolkit.Data.Linq;
    using JetBrains.Annotations;
    using SmartApp;

    public static class OutboxHelper
    {
        /// <summary>
        /// Gets the outbox manager.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <returns></returns>
        [NotNull]
        public static IOutboxManager GetOutboxManager(
            [NotNull] this IServiceProvider provider)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            return provider.GetRequiredService<IOutboxManager>();
        }

		#region Messages
		[NotNull]
		public static Table<DataModel.IOutboxMessage> OutboxMessages([NotNull] this IDataContext db)
		{
			return db.GetTable<DataModel.IOutboxMessage>();
		}

        [NotNull]
        public static IQueryable<DataModel.IOutboxMessage> OutboxMessages(
			[NotNull] this IDataContext db,
            [NotNull] Expression<Func<DataModel.IOutboxMessage, bool>> predicate)
        {
			return db.GetTable(predicate);
        }

        /// <summary>
        /// Adds the outbox message.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="message">The message.</param>
        public static void AddOutboxMessage(
            [NotNull] IServiceProvider provider,
            [NotNull] IOutboxMessage message)
        {
            if (provider == null)
            {
                throw new ArgumentNullException("provider");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            ITagLineManager tagLineManager = provider.GetRequiredService<ITagLineManager>();
            string tagline = tagLineManager.GetTagLine(tagLineManager.FindAppropriateTagLine(message.ForumId));

			using (var db = provider.CreateDBContext())
            {
                Table<DataModel.IOutboxMessage> outboxMessages = db.OutboxMessages();

                outboxMessages
                    .Value(_ => _.ForumID, () => message.ForumId)
                    .Value(_ => _.ReplyToID, () => message.ReplyId)
                    .Value(_ => _.Date, () => DateTime.Now)
                    .Value(_ => _.Subject, () => message.Subject)
                    .Value(_ => _.Body, () => message.Message)
                    .Value(_ => _.Hold, () => message.Hold)
                    .Value(_ => _.Tagline, () => tagline)
                    .Insert();
            }
        }

        #endregion

        #region Rates

        /// <summary>
        /// Outboxes the rates.
        /// </summary>
        /// <param name="dbMgr">The db MGR.</param>
        /// <returns></returns>
        [NotNull]
        public static Table<DataModel.IOutboxRate> OutboxRates(
			[NotNull] this IDataContext db)
        {
			return db.GetTable<DataModel.IOutboxRate>();
        }

        /// <summary>
        /// Outboxes the rates.
        /// </summary>
        /// <param name="dbMgr">The db MGR.</param>
        /// <param name="predicate">The predicate.</param>
        /// <returns></returns>
        [NotNull]
        public static IQueryable<DataModel.IOutboxRate> OutboxRates(
			[NotNull] this IDataContext db,
            Expression<Func<DataModel.IOutboxRate, bool>> predicate)
        {
			return db.GetTable(predicate);
        }

        #endregion

        #region Download topics

        /// <summary>
        /// Downloads the topics.
        /// </summary>
        /// <param name="dbMgr">The db MGR.</param>
        /// <returns></returns>
        [NotNull]
		public static Table<DataModel.IDownloadTopic> DownloadTopics([NotNull] this IDataContext db)
        {
			return db.GetTable<DataModel.IDownloadTopic>();
        }

        /// <summary>
        /// Downloads the topics.
        /// </summary>
        /// <param name="dbMgr">The db MGR.</param>
        /// <param name="predicate">The predicate.</param>
        /// <returns></returns>
        [NotNull]
        public static IQueryable<DataModel.IDownloadTopic> DownloadTopics(
			[NotNull] this IDataContext db,
            Expression<Func<DataModel.IDownloadTopic, bool>> predicate)
        {
			return db.GetTable(predicate);
        }

        #endregion
    }
}